package cc.shacocloud.mirage.restful;

import cc.shacocloud.mirage.utils.MethodParameter;
import cc.shacocloud.mirage.utils.collection.SelfSortList;
import cc.shacocloud.mirage.utils.comparator.AnnotationOrderComparator;
import io.vertx.core.Future;
import io.vertx.core.buffer.Buffer;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;

import java.util.Collections;
import java.util.List;

/**
 * 通过委派给已注册 {@link HandleMethodReturnValueHandler}的列表来解析方法参数。
 * <p>
 * 先前解析的方法参数将被缓存，以加快查找速度。
 */
@Slf4j
public class HandleMethodReturnValueHandlerComposite implements HandleMethodReturnValueHandler {
    
    private final List<HandleMethodReturnValueHandler> returnValueHandlers = new SelfSortList<>(AnnotationOrderComparator.INSTANCE::getOrder);
    
    /**
     * 返回带有已注册处理程序的只读列表，或者返回一个空列表。
     */
    public List<HandleMethodReturnValueHandler> getHandlers() {
        return Collections.unmodifiableList(this.returnValueHandlers);
    }
    
    /**
     * 循环已注册的 {@link HandleMethodReturnValueHandler} 寻找支持给定的 {@linkplain MethodParameter } 方法参数的处理器
     */
    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return getReturnValueHandler(returnType) != null;
    }
    
    @Nullable
    private HandleMethodReturnValueHandler getReturnValueHandler(MethodParameter returnType) {
        for (HandleMethodReturnValueHandler handler : this.returnValueHandlers) {
            if (handler.supportsReturnType(returnType)) {
                return handler;
            }
        }
        return null;
    }
    
    /**
     * 循环已注册的 {@link HandleMethodArgumentResolver}
     * 寻找支持给定的 {@linkplain MethodParameter } 方法参数的处理器处理执行
     *
     * @throws IllegalArgumentException 如果找不到合适的参数解析器则抛出例外！
     */
    @Override
    public Future<Buffer> handleReturnValue(HttpResponse response, MethodParameter returnType, Object returnValue) {
        HandleMethodReturnValueHandler handler = selectHandler(returnType);
        
        if (handler == null) {
            return Future.failedFuture(new IllegalArgumentException("未知的返回值类型: " + returnValue.getClass()));
        }
        
        if (log.isDebugEnabled()) {
            log.debug("匹配到结果解析处理器：" + handler);
        }
        
        return handler.handleReturnValue(response, returnType, returnValue);
    }
    
    @Nullable
    private HandleMethodReturnValueHandler selectHandler(MethodParameter returnType) {
        for (HandleMethodReturnValueHandler handler : this.returnValueHandlers) {
            if (handler.supportsReturnType(returnType)) {
                return handler;
            }
        }
        return null;
    }
    
    /**
     * 添加 {@link HandleMethodReturnValueHandler}.
     */
    public HandleMethodReturnValueHandlerComposite addHandler(HandleMethodReturnValueHandler handler) {
        this.returnValueHandlers.add(handler);
        return this;
    }
    
    /**
     * 添加 {@link HandleMethodReturnValueHandler}
     */
    public HandleMethodReturnValueHandlerComposite addHandlers(@Nullable List<? extends HandleMethodReturnValueHandler> handlers) {
        
        if (handlers != null && !handlers.isEmpty()) {
            this.returnValueHandlers.addAll(handlers);
        }
        return this;
    }
    
}
